package com.cipe.cmrs.model;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;

/**
 * @author Incepio
 * 
 */
@Entity
@Table(name = "projectreports")
@SuppressWarnings("serial")
@NamedQueries({
	@NamedQuery(name="findProjectReportsByProjectId", query="select o from Projectreport o where o.cipeproject.id = :projectId order by o.id"),
	@NamedQuery(name="findProjectReportsByPaymentRequestId", query="select distinct o from Projectreport o inner join o.cipeproject project inner join project.paymentrequestlineitems lineitem where lineitem.paymentrequest.id = :paymentRequestId order by o.id")
})
public class Projectreport extends BaseAuditEntity {

	@Transient
	String message;
	@Transient
	String prc;
	/**
	 * Attribute reportdesc.
	 */
	@Column
	private String reportdesc;

	/**
	 * Attribute reportstartdate.
	 */
	@Column
	private Timestamp reportstartdate;

	/**
	 * Attribute reportattachemnt.
	 */
	@Column
	private String reportattachement;

	/**
	 * Attribute type.
	 */
	@Column
	private String type;

	/**
	 * Attribute cipegrantnumber.
	 */
	@Column
	private String cipegrantnumber;

	/**
	 * Attribute acronym.
	 */
	@Column
	private String acronym;

	/**
	 * Attribute reportperiod1.
	 */
	@Column
	private Timestamp reportperiod1;

	/**
	 * Attribute reportperiod2.
	 */
	@Column
	private Timestamp reportperiod2;

	/**
	 * Attribute reportdue.
	 */
	@Column
	private Timestamp reportdue;

	/**
	 * Attribute reportreceived.
	 */
	@Column
	private Timestamp reportreceived;

	/**
	 * Attribute final.
	 */
	@Column(name="final_str")
	private Boolean finalStr;
	
	@Column
	private Boolean approvedbyfinance;

	/**
	 * Attribute qtr.
	 */
	@Column
	private BigDecimal qtr;

	/**
	 * Attribute reporttogrants.
	 */
	@Column
	private Timestamp reporttogrants;

	/**
	 * Attribute receivedingrants.
	 */
	@Column
	private Timestamp receivedingrants;

	/**
	 * Attribute notation.
	 */
	@Column
	private String notation;

	/**
	 * Attribute finalperiod1.
	 */
	@Column
	private Timestamp finalperiod1;

	/**
	 * Attribute finalperiod2.
	 */
	@Column
	private Timestamp finalperiod2;

	/**
	 * Attribute finaldue.
	 */
	@Column
	private Timestamp finaldue;

	/**
	 * Attribute finalreceived.
	 */
	@Column
	private Timestamp finalreceived;

	/**
	 * Attribute projects
	 */
    @ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "projectid")
	private Cipeproject cipeproject;

	/**
	 * List of Imp
	 */
	@OneToMany(mappedBy = "projectreport")
	private List<Imp> imps = null;

	/**
	 *  The Default constructor
	 */
	public Projectreport() { }
	
	/**
	 * An overloaded constructor.
	 * @param type sets the type of report
	 */
	public Projectreport(String type) {
		this.type = type;
	}
	
	/**
	 * @return reportdesc
	 */

	public String getReportdesc() {
		return reportdesc;
	}

	/**
	 * @param reportdesc
	 *            new value for reportdesc
	 */
	public void setReportdesc(String reportdesc) {
		this.reportdesc = reportdesc;
	}

	/**
	 * @return reportstartdate
	 */

	public Timestamp getReportstartdate() {
		return reportstartdate;
	}

	/**
	 * @param reportstartdate
	 *            new value for reportstartdate
	 */
	public void setReportstartdate(Timestamp reportstartdate) {
		this.reportstartdate = reportstartdate;
	}

	/**
	 * @return reportattachemnt
	 */

	public String getReportattachement() {
		return reportattachement;
	}

	/**
	 * @return type
	 */

	public String getType() {
		return type;
	}

	/**
	 * @param type
	 *            new value for type
	 */
	public void setType(String type) {
		this.type = type;
	}

	/**
	 * @return cipegrantnumber
	 */

	public String getCipegrantnumber() {
		return cipegrantnumber;
	}

	/**
	 * @param cipegrantnumber
	 *            new value for cipegrantnumber
	 */
	public void setCipegrantnumber(String cipegrantnumber) {
		this.cipegrantnumber = cipegrantnumber;
	}

	/**
	 * @return acronym
	 */

	public String getAcronym() {
		return acronym;
	}

	/**
	 * @param acronym
	 *            new value for acronym
	 */
	public void setAcronym(String acronym) {
		this.acronym = acronym;
	}

	/**
	 * @return reportperiod1
	 */

	public Timestamp getReportperiod1() {
		return reportperiod1;
	}

	/**
	 * @param reportperiod1
	 *            new value for reportperiod1
	 */
	public void setReportperiod1(Timestamp reportperiod1) {
		this.reportperiod1 = reportperiod1;
	}

	/**
	 * @return reportperiod2
	 */

	public Timestamp getReportperiod2() {
		return reportperiod2;
	}

	/**
	 * @param reportperiod2
	 *            new value for reportperiod2
	 */
	public void setReportperiod2(Timestamp reportperiod2) {
		this.reportperiod2 = reportperiod2;
	}

	/**
	 * @return reportdue
	 */

	public Timestamp getReportdue() {
		return reportdue;
	}

	/**
	 * @param reportdue
	 *            new value for reportdue
	 */
	public void setReportdue(Timestamp reportdue) {
		this.reportdue = reportdue;
	}

	/**
	 * @return reportreceived
	 */

	public Timestamp getReportreceived() {
		return reportreceived;
	}

	/**
	 * @param reportreceived
	 *            new value for reportreceived
	 */
	public void setReportreceived(Timestamp reportreceived) {
		this.reportreceived = reportreceived;
	}

	/**
	 * @return qtr
	 */

	public BigDecimal getQtr() {
		return qtr;
	}

	/**
	 * @param qtr
	 *            new value for qtr
	 */
	public void setQtr(BigDecimal qtr) {
		this.qtr = qtr;
	}

	/**
	 * @return reporttogrants
	 */

	public Timestamp getReporttogrants() {
		return reporttogrants;
	}

	/**
	 * @param reporttogrants
	 *            new value for reporttogrants
	 */
	public void setReporttogrants(Timestamp reporttogrants) {
		this.reporttogrants = reporttogrants;
	}

	/**
	 * @return receivedingrants
	 */

	public Timestamp getReceivedingrants() {
		return receivedingrants;
	}

	/**
	 * @param receivedingrants
	 *            new value for receivedingrants
	 */
	public void setReceivedingrants(Timestamp receivedingrants) {
		this.receivedingrants = receivedingrants;
	}

	/**
	 * @return notation
	 */

	public String getNotation() {
		return notation;
	}

	/**
	 * @param notation
	 *            new value for notation
	 */
	public void setNotation(String notation) {
		this.notation = notation;
	}

	/**
	 * @return finalperiod1
	 */

	public Timestamp getFinalperiod1() {
		return finalperiod1;
	}

	/**
	 * @param finalperiod1
	 *            new value for finalperiod1
	 */
	public void setFinalperiod1(Timestamp finalperiod1) {
		this.finalperiod1 = finalperiod1;
	}

	/**
	 * @return finalperiod2
	 */

	public Timestamp getFinalperiod2() {
		return finalperiod2;
	}

	/**
	 * @param finalperiod2
	 *            new value for finalperiod2
	 */
	public void setFinalperiod2(Timestamp finalperiod2) {
		this.finalperiod2 = finalperiod2;
	}

	/**
	 * @return finaldue
	 */

	public Timestamp getFinaldue() {
		return finaldue;
	}

	/**
	 * @param finaldue
	 *            new value for finaldue
	 */
	public void setFinaldue(Timestamp finaldue) {
		this.finaldue = finaldue;
	}

	/**
	 * @return finalreceived
	 */

	public Timestamp getFinalreceived() {
		return finalreceived;
	}

	/**
	 * @param finalreceived
	 *            new value for finalreceived
	 */
	public void setFinalreceived(Timestamp finalreceived) {
		this.finalreceived = finalreceived;
	}


	/**
	 * Get the list of Imp
	 */

	public List<Imp> getImps() {
		return this.imps;
	}

	/**
	 * Set the list of Imp
	 */
	public void setImps(List<Imp> imps) {
		this.imps = imps;
	}

	public Boolean getFinalStr() {
		return finalStr;
	}

	public void setFinalStr(Boolean finalStr) {
		this.finalStr = finalStr;
	}

	public Cipeproject getCipeproject() {
		return cipeproject;
	}

	public void setCipeproject(Cipeproject cipeproject) {
		this.cipeproject = cipeproject;
	}

	public Boolean getApprovedbyfinance() {
		return approvedbyfinance;
	}

	public void setApprovedbyfinance(Boolean approvedbyfinance) {
		this.approvedbyfinance = approvedbyfinance;
	}

	public void setReportattachement(String reportattachement) {
		this.reportattachement = reportattachement;
	}

	/**
	 * @return the message
	 */
	public String getMessage() {
		return message;
	}

	/**
	 * @param message the message to set
	 */
	public void setMessage(String message) {
		this.message = message;
	}

	/**
	 * @return the prc
	 */
	public String getPrc() {
		return prc;
	}

	/**
	 * @param prc the prc to set
	 */
	public void setPrc(String prc) {
		this.prc = prc;
	}
	
	@Transient
	public boolean isNarrativeReceivedDateOverDue() {
		return compareDates(reportdue, new Date());
	}

	@Transient
	public boolean isFinancialAllDatesOverDue() {
		return compareDates(reportdue, new Date()) && (reportreceived == null);
	}
	
	@Transient
	public boolean isFinancialGrantDatesOverDue() {
		return compareDates(reportreceived, new Date()) && (reporttogrants == null);
	}
	
	@Transient
	public boolean isFinancialInGrantDateOverDue() {
		return compareDates(reporttogrants, new Date()) && (receivedingrants == null);
	}	
	
	@Transient	
	private boolean compareDates(Timestamp date1, Date date2) {
		if(date1 != null && date2 != null) {
			Calendar cal1 = Calendar.getInstance();
			cal1.setTimeInMillis(date1.getTime());
			cal1.set(Calendar.HOUR_OF_DAY, 12);
			cal1.set(Calendar.MINUTE, 0);
			cal1.set(Calendar.SECOND, 0);
	  		
	  		Calendar cal2 = Calendar.getInstance(); 
	  		cal2.setTime(date2);
			cal1.set(Calendar.HOUR_OF_DAY, 12);
			cal1.set(Calendar.MINUTE, 0);
			cal1.set(Calendar.SECOND, 0);
			
			return ((cal1.compareTo(cal2) < 0) ? true : false);
		} else {
			return false;
		}
	}
	
    @Transient
    public boolean isEmpty() {
        return this.getReportperiod1() == null && this.getReportperiod2() == null && this.getReportdue() == null
            && this.getFinalStr() == null && this.getReportreceived() == null && this.getReporttogrants() == null
            && this.getReceivedingrants() == null;
    }
}